﻿#region 참조 네임스페이스

using System.Runtime.InteropServices;

#endregion

namespace Skying.Runtime.InteropServices
{
	/// <summary>
	/// <see cref="System.Runtime.InteropServices.Marshal"/>에 대한 확장 메서드를 제공한다.
	/// </summary>
	public class MarshalExtensions
	{
		/// <summary>
		/// 구조체에 대한 바이너리를 구조체로 변환한다.
		/// </summary>
		/// <typeparam name="T">변환할 구조체의 타입을 나타낸다.</typeparam>
		/// <param name="binary">구조체에 대한 바이너리를 설정한다.</param>
		/// <returns>변환된 구조체를 반환한다.</returns>
		public static T ConvertBinaryToStructure<T>(byte[] binary) where T : struct
		{
			// 구조체에 대한 바이너리에 대해서 핸들을 할당한다.
			GCHandle gcHandle = GCHandle.Alloc(binary, GCHandleType.Pinned);

			T result = default(T);

			try
			{
				// 바이너리에 대한 핸들을 가져와 타입에 대한 구조체로 변환한다.
				result = (T)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(T));
			}
			finally
			{
				gcHandle.Free();
			}

			return result;
		}
	}
}